package com.xbongbong.saas.service.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.service.FormConfigService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.FormConfigEnablePoJo;
import com.xbongbong.pro.form.pojo.FormConfigPoJo;
import com.xbongbong.pro.form.pojo.dto.FormConfigAddBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormConfigGetDTO;
import com.xbongbong.pro.form.pojo.dto.FormConfigGetMultiDTO;
import com.xbongbong.pro.form.pojo.dto.FormConfigSetDTO;
import com.xbongbong.pro.form.pojo.vo.FormConfigAddBatchVO;
import com.xbongbong.pro.form.pojo.vo.FormConfigGetVO;
import com.xbongbong.pro.form.pojo.vo.FormConfigMultiGetVO;
import com.xbongbong.pro.form.pojo.vo.FormConfigSetVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/5/21 16:54
 * @since v1.0
 */
@Service("formConfigService")
public class FormConfigServiceImpl implements FormConfigService {
    private static final Logger LOG = LoggerFactory.getLogger(FormConfigServiceImpl.class);
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private PaasFormModel paasFormModel;

    @Override
    public FormConfigGetVO enableCustomerCheckRepeat(BaseDTO baseDTO) throws XbbException {
        String corpid = baseDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(StringConstant.BUSINESS_TYPE, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        List<String> configList = new ArrayList<>();
        configList.add(FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfig());
        configList.add(FormConfigEnum.CUSTOMER_PHONE_CHECK_SET.getConfig());
        param.put("configIn", configList);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<FormConfigEntity> formConfigEntityList = formConfigModel.findEntitys(param);
        List<PaasFormEntityExt> enableFormList = paasFormModel.getEnableFormListDistributor(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), 0);
        List<Long> configFormIdIn = new ArrayList<>();
        List<Long> enableFormIdIn = new ArrayList<>();
        formConfigEntityList.forEach(formConfigEntity -> configFormIdIn.add(formConfigEntity.getFormId()));
        Map<Long, PaasFormEntityExt> formMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        enableFormList.forEach(entity -> {
            enableFormIdIn.add(entity.getId());
            formMap.put(entity.getId(), entity);
        });
        List<Long> tempEnableList = new ArrayList<>(enableFormIdIn);
        enableFormIdIn.removeAll(configFormIdIn);
        configFormIdIn.removeAll(tempEnableList);
        if (!enableFormIdIn.isEmpty()) {
            for (Long formId : enableFormIdIn) {
                FormConfigEntity nameConfigEntity = new FormConfigEntity(corpid, formId, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfig(), FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfigValue());
                FormConfigEntity phoneConfigEntity = new FormConfigEntity(corpid, formId, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), FormConfigEnum.CUSTOMER_PHONE_CHECK_SET.getConfig(), FormConfigEnum.CUSTOMER_PHONE_CHECK_SET.getConfigValue());
                formConfigEntityList.add(nameConfigEntity);
                formConfigEntityList.add(phoneConfigEntity);
            }
            formConfigModel.insertBatch(formConfigEntityList);
        }
        if (!configFormIdIn.isEmpty()) {
            param.put("formIdIn", configFormIdIn);
            List<FormConfigEntity> needDelConfigList = formConfigModel.findEntitys(param);
            List<Long> needDelConfigIdIn = new ArrayList<>();
            needDelConfigList.forEach(formConfigEntity -> needDelConfigIdIn.add(formConfigEntity.getId()));
            formConfigModel.deleteBatch(needDelConfigIdIn, corpid);
            formConfigEntityList.removeAll(needDelConfigList);
        }
        FormConfigGetVO formConfigGetVO = new FormConfigGetVO();
        Map<Long, List<FormConfigEntity>> configMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FormConfigEnablePoJo> formConfig = new ArrayList<>();
        for (FormConfigEntity formConfigEntity : formConfigEntityList) {
            List<FormConfigEntity> configGroupByForm = new ArrayList<>();
            Long formId = formConfigEntity.getFormId();
            if (configMap.containsKey(formId)) {
                configGroupByForm = configMap.get(formId);
            }
            configGroupByForm.add(formConfigEntity);
            configMap.put(formId, configGroupByForm);
        }
        for (Map.Entry<Long, List<FormConfigEntity>> entry: configMap.entrySet()) {
            FormConfigEnablePoJo formConfigEnablePoJo = new FormConfigEnablePoJo();
            formConfigEnablePoJo.setFormId(entry.getKey());
            formConfigEnablePoJo.setFormName(formMap.get(entry.getKey()).getName());
            List<FormConfigEntity> configEntityList = entry.getValue();
            List<FormConfigPoJo> configEnablePoJoList = new ArrayList<>();
            for (FormConfigEntity formConfigEntity : configEntityList) {
                FormConfigPoJo formConfigPoJo = new FormConfigPoJo(formConfigEntity.getConfig(), Integer.valueOf(formConfigEntity.getConfigValue()), FormConfigEnum.getByConfig(formConfigEntity.getConfig()).getName());
                configEnablePoJoList.add(formConfigPoJo);
            }
            formConfigEnablePoJo.setConfigList(configEnablePoJoList);
            formConfig.add(formConfigEnablePoJo);
        }
        formConfigGetVO.setFormConfig(formConfig);
        return formConfigGetVO;
    }

    @Override
    public FormConfigSetVO enable(FormConfigSetDTO formConfigSetDTO) throws XbbException {
        Map<String ,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigSetDTO.getConfig());
        if (Objects.isNull(formConfigEnum)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        String configValue = formConfigSetDTO.getConfigValue();
        configValue = BasicConstant.IS_USE.toString().equals(configValue) ? configValue : BasicConstant.NO_USE.toString();
        param.put("config", formConfigEnum.getConfig());
        param.put("formId", formConfigSetDTO.getFormId());
        param.put(ParameterConstant.CORPID, formConfigSetDTO.getCorpid());
        List<FormConfigEntity> formConfigEntityList = formConfigModel.findEntitys(param);
        FormConfigEntity formConfigEntity;
        //如果获取到的实体记录是空的话
        if (formConfigEntityList.isEmpty()) {
            formConfigEntity = new FormConfigEntity();
            BeanUtil.copyProperties(formConfigSetDTO, formConfigEntity);
            formConfigEntity.setBusinessType(formConfigEnum.getBusinessType());
            formConfigEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            try {
                formConfigModel.insert(formConfigEntity);
            } catch (Exception e) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            //如果获取到的实体记录不是空的话
        } else {
            formConfigEntity = formConfigEntityList.get(0);
            if (Objects.equals(formConfigEnum.getConfig(), FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfig()) && Objects.equals(configValue, BasicConstant.NO_USE.toString())) {
                param.put("config", FormConfigEnum.CUSTOMER_PHONE_CHECK_SET.getConfig());
                List<FormConfigEntity> phoneConfigEntityList = formConfigModel.findEntitys(param);
                if (!phoneConfigEntityList.isEmpty()) {
                    FormConfigEntity phoneConfig = phoneConfigEntityList.get(0);
                    if (Objects.equals(phoneConfig.getConfigValue(), BasicConstant.NO_USE.toString())) {
                        throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201030);
                    }
                }
            }
            if (Objects.equals(formConfigEnum.getConfig(), FormConfigEnum.CUSTOMER_PHONE_CHECK_SET.getConfig()) && Objects.equals(configValue, BasicConstant.NO_USE.toString())) {
                param.put("config", FormConfigEnum.CUSTOMER_NAME_CHECK_SET.getConfig());
                List<FormConfigEntity> nameConfigEntityList = formConfigModel.findEntitys(param);
                if (!nameConfigEntityList.isEmpty()) {
                    FormConfigEntity nameConfig = nameConfigEntityList.get(0);
                    if (Objects.equals(nameConfig.getConfigValue(), BasicConstant.NO_USE.toString())) {
                        throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201030);
                    }
                }
            }
            formConfigEntity.setConfigValue(configValue);
            try {
//                formConfigModel.update(formConfigEntity);
                formConfigModel.update(formConfigEntity);
            } catch (Exception e) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }
        return new FormConfigSetVO();
    }

    @Override
    public FormConfigGetVO getFormConfig(FormConfigGetDTO formConfigGetDTO) throws XbbException {
        //通过工具类将formConfigGetDTO对象转换成map集合
        Map<String ,Object> param = BeanUtil.convertBean2Map(formConfigGetDTO, true);
        //获取符合查询条件的实体类，将该实体类存放在一个list集合中
        List<FormConfigEntity> formConfigEntityList = formConfigModel.findEntitys(param);
        //创建一个表单对象formConfigGetVO
        FormConfigGetVO formConfigGetVO = new FormConfigGetVO();
        //创建一个集合，该集合的value值用于存放含有FormConfigEntity实体的list集合
        Map<Long, List<FormConfigEntity>> configMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //创建一个集合用于存放FormConfigEnablePoJo实体类
        List<FormConfigEnablePoJo> formConfig = new ArrayList<>();
        //遍历formConfigEntityList集合，之后创建一个新的集合用于存放FormConfigEntity实体类
        for (FormConfigEntity formConfigEntity : formConfigEntityList) {
            List<FormConfigEntity> configGroupByForm = new ArrayList<>();
            //获取实体类formConfigEntity的formId
            Long formId = formConfigEntity.getFormId();
            //判断configMap中是否包含获取到的formId,如果有的话就根据获取到的formId获取configMap集合中的含有FormConfigEntity实体的集合，并将该集合存放在configGroupByForm集合中
            if (configMap.containsKey(formId)) {
                configGroupByForm = configMap.get(formId);
            }
            //将遍历到的formConfigEntity实体添加到configGroupByForm集合中
            configGroupByForm.add(formConfigEntity);
            configMap.put(formId, configGroupByForm);
        }
        for (Map.Entry<Long, List<FormConfigEntity>> entry: configMap.entrySet()) {
            FormConfigEnablePoJo formConfigEnablePoJo = new FormConfigEnablePoJo();
            formConfigEnablePoJo.setFormId(entry.getKey());
            List<FormConfigEntity> configEntityList = entry.getValue();
            List<FormConfigPoJo> configEnablePoJoList = new ArrayList<>();
            for (FormConfigEntity formConfigEntity : configEntityList) {
                FormConfigPoJo formConfigPoJo = new FormConfigPoJo(formConfigEntity.getConfig(), Integer.valueOf(formConfigEntity.getConfigValue()), FormConfigEnum.getByConfig(formConfigEntity.getConfig()).getName());
                configEnablePoJoList.add(formConfigPoJo);
            }
            formConfigEnablePoJo.setConfigList(configEnablePoJoList);
            formConfig.add(formConfigEnablePoJo);
        }
        formConfigGetVO.setFormConfig(formConfig);
        return formConfigGetVO;
    }

    @Override
    public FormConfigAddBatchVO saveBatch(FormConfigAddBatchDTO formConfigAddBatchDTO) throws XbbException {
        FormConfigAddBatchVO formConfigAddBatchVO = new FormConfigAddBatchVO();
        try {
            Map<String, Object> params = BeanUtil.convertBean2Map(formConfigAddBatchDTO, true);
            List<String> configList = new ArrayList<>();
            //前端传入的值
            List<FormConfigEntity> formConfigEntities = new ArrayList<>();
            formConfigAddBatchDTO.getFormConfigList().forEach(formConfigAddDTO -> {
                FormConfigEntity formConfigEntity = new FormConfigEntity();
                BeanUtil.copyProperties(formConfigAddDTO, formConfigEntity);
                formConfigEntity.setCorpid(formConfigAddBatchDTO.getCorpid());
                formConfigEntity.setSaasMark(formConfigAddBatchDTO.getSaasMark());
                formConfigEntity.setBusinessType(formConfigAddBatchDTO.getBusinessType());
                formConfigEntity.setFormId(formConfigAddBatchDTO.getFormId());
                configList.add(formConfigAddDTO.getConfig());
                formConfigEntities.add(formConfigEntity);
            });

            params.put("configIn", configList);
            params.put("start", 0);
            params.put("pageNum", configList.size());
            params.put("del", DelEnum.NORMAL.getDel());
            //数据库有的值
            List<FormConfigEntity> formConfigEntityDBList = formConfigModel.findEntitys(params);

            Map<String, FormConfigEntity> formConfigMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (FormConfigEntity entity : formConfigEntityDBList) {
                formConfigMap.put(entity.getConfig(), entity);
            }
            List<FormConfigEntity> insertConfigList = new ArrayList<>();
            List<FormConfigEntity> updateConfigList = new ArrayList<>();

            if (formConfigEntityDBList.isEmpty()) {
                for (FormConfigEntity entity : formConfigEntities) {
                    long now = DateTimeUtil.getInt();
                    entity.setAddTime(now);
                    entity.setUpdateTime(now);
                    insertConfigList.add(entity);
                }
            } else if (formConfigEntityDBList.size() != formConfigEntities.size()) {
                for (FormConfigEntity entity : formConfigEntities) {
                    if (formConfigMap.containsKey(entity.getConfig())) {
                        long now = DateTimeUtil.getInt();
                        entity.setId(formConfigMap.get(entity.getConfig()).getId());
                        entity.setUpdateTime(now);
                        updateConfigList.add(entity);
                    } else {
                        long now = DateTimeUtil.getInt();
                        entity.setAddTime(now);
                        entity.setUpdateTime(now);
                        insertConfigList.add(entity);
                    }
                }
            } else {
                for (FormConfigEntity entity : formConfigEntities) {
                    long now = DateTimeUtil.getInt();
                    entity.setId(formConfigMap.get(entity.getConfig()).getId());
                    entity.setUpdateTime(now);
                    updateConfigList.add(entity);
                }
            }

            if (!insertConfigList.isEmpty()) {
                formConfigModel.insertBatch(insertConfigList);
            }
            if (!updateConfigList.isEmpty()) {
                formConfigModel.updateBatch(updateConfigList, formConfigAddBatchDTO.getCorpid());
            }

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("FormConfigServiceImpl.saveBatch批量保存数据库出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formConfigAddBatchVO;
    }


    @Override
    public FormConfigMultiGetVO getButtonByFormId(FormConfigGetMultiDTO formConfigGetMultiDTO) throws XbbException {
        FormConfigMultiGetVO formConfigMultiGetVO = new FormConfigMultiGetVO();
        try {
            List<String> configList = new ArrayList<>();
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(formConfigGetMultiDTO.getBusinessType());
            switch (xbbRefTypeEnum) {
                //如果是客户阶段则添加客户阶段的跨越按钮以及回退按钮
                case CUSTOMER_MANAGEMENT:
                    break;
                //如果是销售阶段则添加销售阶段的跨越按钮以及回退按钮
                case SALES_OPPORTUNITY:
                    break;
                case CLUE:
                    break;
                default:
                    break;
            }
            String corpid = formConfigGetMultiDTO.getCorpid();
            Long formId = formConfigGetMultiDTO.getFormId();
            //调用查询多个按钮实体的方法
            List<FormConfigEntity> formConfigEntity = formConfigModel.getButtonEntityByFormId(corpid, formId, configList);
            //创建一个map集合用于存放遍历查询到的config以及按钮实体
            Map<String, FormConfigEntity> formConfigEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (FormConfigEntity configEntity : formConfigEntity) {
                formConfigEntityMap.put(configEntity.getConfig(),configEntity);
            }

            //创建一个集合用于存放FormConfigEntity实体
            List<FormConfigEntity> formConfigEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            //遍历configList，formConfigEntityMap根据遍历到的config查找对应的config实体值
            for (String str : configList) {
                FormConfigEntity configEntity = formConfigEntityMap.get(str);
                FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(str);
                if (Objects.isNull(configEntity)){
                    configEntity = new FormConfigEntity();
                    configEntity.setConfig(formConfigEnum.getConfig());
                    configEntity.setConfigValue(formConfigEnum.getConfigValue());
                }
                configEntity.setButtonName(formConfigEnum.getName());
                formConfigEntityList.add(configEntity);
            }
            formConfigMultiGetVO.setList(formConfigEntityList);
        } catch (Exception e) {
            LOG.error("paasFormData数据库查询表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formConfigMultiGetVO;
    }

    @Override
    public FormConfigEntity getProductDataSet(FormConfigGetMultiDTO formConfigGetMultiDTO) throws XbbException {
        FormConfigEntity formConfigEntity = new FormConfigEntity();
        String corpid = formConfigGetMultiDTO.getCorpid();
        Long formId = formConfigGetMultiDTO.getFormId();
        String config = FormConfigEnum.PRODUCT_DATA_ISOLATION.getConfig();
        FormConfigEntity configEntity = formConfigModel.getByConfig(config,corpid,formId,SaasMarkEnum.SAAS.getCode(),XbbRefTypeEnum.PRODUCT.getCode());

        formConfigEntity.setFormId(formId);
        formConfigEntity.setCorpid(corpid);
        formConfigEntity.setBusinessType(XbbRefTypeEnum.PRODUCT.getCode());
        formConfigEntity.setConfig(FormConfigEnum.PRODUCT_DATA_ISOLATION.getConfig());
        // 如果没有 走默认值
        if (Objects.isNull(configEntity)){
            formConfigEntity.setConfigValue(FormConfigEnum.PRODUCT_DATA_ISOLATION.getConfigValue());
        }else {
            formConfigEntity.setConfigValue(configEntity.getConfigValue());
        }
        return formConfigEntity;
    }

    @Override
    public BaseVO saveProductDataSet(FormConfigSetDTO formConfigSetDTO) throws XbbException {
        BaseVO baseVO = new BaseVO();

        String corpid = formConfigSetDTO.getCorpid();
        Long formId = formConfigSetDTO.getFormId();
        String config = FormConfigEnum.PRODUCT_DATA_ISOLATION.getConfig();
        String configValue = formConfigSetDTO.getConfigValue();
        FormConfigEntity configEntity = formConfigModel.getByConfig(config,corpid,formId,SaasMarkEnum.SAAS.getCode(),XbbRefTypeEnum.PRODUCT.getCode());
        // 如果数据库中有数据就更新
        if (Objects.nonNull(configEntity)){
            configEntity.setConfigValue(configValue);
            configEntity.setUpdateTime(DateTimeUtil.getInt());
            formConfigModel.update(configEntity);
        }else {
            // 没有就插入
            FormConfigEntity formConfigEntity = new FormConfigEntity();
            formConfigEntity.setFormId(formId);
            formConfigEntity.setCorpid(corpid);
            formConfigEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formConfigEntity.setBusinessType(XbbRefTypeEnum.PRODUCT.getCode());
            formConfigEntity.setConfig(FormConfigEnum.PRODUCT_DATA_ISOLATION.getConfig());
            formConfigEntity.setConfigValue(configValue);
            formConfigEntity.setDel(DelEnum.NORMAL.getDel());
            formConfigEntity.setAddTime(DateTimeUtil.getInt());
            formConfigEntity.setUpdateTime(DateTimeUtil.getInt());
            formConfigModel.insert(formConfigEntity);
        }
        return baseVO;
    }


}
